﻿using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace CoreLibrary {

    public class FileNameUtil {

        private static readonly HashSet<char> AllowedListFileNameChar = new HashSet<char> {
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
            '0','1','2','3','4','5','6','7','8','9',
            '_','-','.'
        };

        private static readonly HashSet<char> ValidFileNameChars = new HashSet<char> {
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
            '0','1','2','3','4','5','6','7','8','9',
            '_','-','.', ' ','(',')','\''
        };

        public static string NormalizeListFileName (string fileNameOrPath) {
            if (string.IsNullOrEmpty(fileNameOrPath)) {
                return string.Empty;
            }

            var prefix = Path.GetFileNameWithoutExtension(fileNameOrPath);
            var filePrefix = GetValidListFilePrefix(prefix);
            var fileExtension = GetExtension(fileNameOrPath, string.Empty);
            return string.Concat(filePrefix, fileExtension);
        }

        public static string NormalizeName (string fileNameOrPath) {
            if (string.IsNullOrEmpty(fileNameOrPath)) {
                return string.Empty;
            }

            var filePrefix = GetPrefix(fileNameOrPath, string.Empty);
            var fileExtension = GetExtension(fileNameOrPath, string.Empty);
            return string.Concat(filePrefix, fileExtension);
        }

        public static string GetPrefix (string fileName, string defaultIfNull) {
            var prefix = GetPrefix(fileName);
            return string.IsNullOrEmpty(prefix) ? defaultIfNull
                                                : prefix;
        }

        public static string GetPrefix (string fileName) {
            var filePrefix = Path.GetFileNameWithoutExtension(fileName);
            return string.IsNullOrEmpty(fileName) ? string.Empty
                                                  : GetValidFilePrefix(filePrefix);
        }

        public static string GetExtension (string fileNameOrPath, string defaultIfNull) {
            var fileExtension = GetExtension(fileNameOrPath);
            return string.IsNullOrEmpty(fileExtension) ? defaultIfNull
                                                       : fileExtension;
        }

        public static string GetExtension (string fileNameOrPath) {
            return string.IsNullOrEmpty(fileNameOrPath) ? string.Empty
                                                        : Path.GetExtension(fileNameOrPath);
        }

        private static string GetValidFilePrefix (string prefix) {
            return new string(prefix.AsEnumerable().Select(c =>
                 ( char.IsControl(c) || !ValidFileNameChars.Contains(c) ) ? '_' : c).ToArray());
        }

        private static string GetValidListFilePrefix (string prefix) {
            return new string(prefix.AsEnumerable().Select(c =>
                 ( char.IsControl(c) || !AllowedListFileNameChar.Contains(c) ) ? '_' : c).ToArray());
        }
    }
}